package com.fight.strive.sys.modules.scheduler;

import com.fight.strive.sys.modules.exception.ExceptionUtils;
import com.fight.strive.sys.modules.mail.StriveMailSender;
import com.fight.strive.sys.modules.scheduler.constants.SchConstants;
import com.fight.strive.sys.modules.scheduler.entity.SchJobEntity;
import com.fight.strive.sys.modules.scheduler.entity.SchRecordEntity;
import com.fight.strive.sys.modules.scheduler.service.SchJobService;
import com.fight.strive.sys.modules.scheduler.service.SchRecordService;
import com.fight.strive.sys.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

@Slf4j
@Component
public class Executor {

    @Resource
    @Lazy
    private SchJobService schJobService;

    @Resource
    private SchRecordService schRecordService;

    @Resource
    private StriveMailSender striveMailSender;

    /**
     * 执行任务
     *
     * @param entity 任务信息
     */
    @Async
    public void execute(SchJobEntity entity) {
        int count = entity.getRetry() + 1;
        while (count > 0) {
            count -= 1;
            // 保存任务执行记录
            SchRecordEntity record = schRecordService.saveJobRecord(entity);
            try {
                // 执行任务逻辑
                schJobService.executeJob(entity);
                // 任务执行成功结束记录
                record.setStatus(SchConstants.SUCCESS);
            } catch (Exception e) {
                // 任务执行错误结束记录
                record.setStatus(SchConstants.ERROR)
                        .setStackTrace(ExceptionUtils.formatStackTrace(
                                ExceptionUtils.getPrintStackTrace(e)));
            }
            // 更新执行记录
            schRecordService.updateJobRecord(record);
            if (StringUtils.equals(
                    record.getStatus(), SchConstants.SUCCESS)) {
                // 如果任务成功结束，退出循环
                break;
            }
            // 重试完后失败的，发送邮件通知
            if (count == 0 && StringUtils.equals(
                    record.getStatus(), SchConstants.ERROR)) {
                striveMailSender.sendSimpleMail("定时调度任务失败",
                        record.getStackTrace(), entity.getEmail());
            }
        }
    }
}
